<?php
namespace app\classes\helper;
use think\Db;

class FuyouHelp
{
    protected $rsa_public_key;        //对方公钥，加密用
    protected $rsa_private_key;        //己方私钥，解密用

    public function __construct($rsa_public_key, $rsa_private_key)
    {
        //富友公钥
        $this->rsa_public_key = $rsa_public_key;
        //商户私钥
        $this->rsa_private_key = $rsa_private_key;
    }

    //加密
    public function publicEncryptRsa($plainData = '')
    {
        if (!is_string($plainData)) {
            return null;
        }
        $encrypted = '';
        $partLen = $this->getPublicKenLen() / 8 - 11;
        $plainData = str_split($plainData, $partLen);
        $publicPEMKey = $this->getPublicKey();
        foreach ($plainData as $chunk) {
            $partialEncrypted = '';
            $encryptionOk = openssl_public_encrypt($chunk, $partialEncrypted, $publicPEMKey, OPENSSL_PKCS1_PADDING);
            if ($encryptionOk === false) {
                return false;
            }
            $encrypted .= $partialEncrypted;
        }
        return base64_encode($encrypted);
    }

    public function getPublicKenLen()
    {
        $pub_id = openssl_get_publickey($this->getPublicKey());
        return openssl_pkey_get_details($pub_id)['bits'];
    }

    public function getPublicKey()
    {
        $public_key = $this->rsa_public_key;
        //这里的public_key，是一行的情况，才是这样处理；如果密钥是以文件形式存放且格式已经是换行了的，就需要用另外的方式，参照demo.php里的取法
        $pubic_pem = chunk_split($public_key, 64, "\n");
        $pubic_pem = "-----BEGIN PUBLIC KEY-----\n" . $pubic_pem . "-----END PUBLIC KEY-----\n";
        return $pubic_pem;
    }

    public function privateDecryptRsa($data = '')
    {
        if (!is_string($data)) {
            return null;
        }
        $decrypted = '';

        $partLen = $this->getPrivateKenLen() / 8;
        $data = str_split(base64_decode($data), $partLen);

        $privatePEMKey = $this->getPrivateKey();

        foreach ($data as $chunk) {
            $partial = '';
            $decryptionOK = openssl_private_decrypt($chunk, $partial, $privatePEMKey, OPENSSL_PKCS1_PADDING);
            if ($decryptionOK === false) {
                return false;
            }
            $decrypted .= $partial;
        }
        return $decrypted;
    }

    public function getPrivateKenLen()
    {
        $pub_id = openssl_get_privatekey($this->getPrivateKey());
        return openssl_pkey_get_details($pub_id)['bits'];
    }

    public function getPrivateKey()
    {
        //这里的private_key，是一行的情况，才是这样处理；如果密钥是以文件形式存放且格式已经是换行了的，就需要用另外的方式，参照demo.php里的取法
        $private_key = $this->rsa_private_key;
        $private_pem = chunk_split($private_key, 64, "\n");
        $private_pem = "-----BEGIN PRIVATE KEY-----\n" . $private_pem . "-----END PRIVATE KEY-----\n";
        return $private_pem;
    }
}